#pragma once

#include <cerrno>
#include <cstring>
#include <sys/epoll.h>
#include "lib/Log.hpp"

class Epoll
{
    const static int g_epoll_num = 512;
public:
    Epoll()
    {
        _epfd = epoll_create(g_epoll_num);
        if(_epfd < 0)
        {
            Messagelog(FATAL, "epoll create error: %d:%s", errno, strerror(errno));
            exit(11);
        }
    }
    
    bool AddSockToEpoll(int sock, uint32_t event)
    {
        struct epoll_event ev;
        ev.data.fd = sock;
        ev.events = event;
        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sock, &ev);
        if(n == 0) Messagelog(DEBUG, "AddSockToEpoll success sock: %d", sock);
        return n == 0;
    }

    bool DeleteSockFromEpoll(int sock)
    {
        struct epoll_event ev;
        ev.data.fd = sock;
        ev.events = 0;
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sock, &ev);
        if(n == 0) Messagelog(DEBUG, "DeleteSockToEpoll success sock: %d", sock);
        return n == 0;
    }

    int EpollWait(epoll_event evevts[], int maxevents, int timeout)
    {
        int n = epoll_wait(_epfd, evevts, maxevents, timeout);
        if(n == -1)
        {
            Messagelog(ERROR, "epoll wait error %d:%s", errno, strerror(errno));
            exit(12);
        }
        return n;
    }

    bool EpollClt(int sock, uint32_t event)
    {
        struct epoll_event ev;
        ev.data.fd = sock;
        ev.events = event;
        int n = epoll_ctl(_epfd, EPOLL_CTL_MOD, sock, &ev);
        return n == 0;
    }

    ~Epoll()
    {
        if(_epfd >= 0) close(_epfd);
    }
private:
    int _epfd;
};